<?php

namespace app\install\controller;
use app\common\service\Sql as SqlService;

class Index extends BaseInstall
{

    public function __construct()
    {
        //执行父类构造函数
        parent::__construct();
    }

    /**
     *安装
     */
    public function index()
    {
        if (file_exists($this->lock_file)) {
            return redirect('/');
        }
        $step = input("step", 1);
        if ($step == 1) {
            return $this->fetch('index/step-1');
        } elseif ($step == 2) {
            //系统变量
            $system_variables = [];
            $phpv = phpversion();
            $os = PHP_OS;
            $server = $_SERVER['SERVER_SOFTWARE'];

            $host = (empty($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_HOST'] : $_SERVER['REMOTE_ADDR']);
            $name = $_SERVER['SERVER_NAME'];

            $verison = !(version_compare(PHP_VERSION, '7.1.0') == -1);
            //pdo
            $pdo = extension_loaded('pdo') && extension_loaded('pdo_mysql');
            $system_variables[] = ["name" => "pdo", "need" => "开启", "status" => $pdo];
            //curl
            $curl = extension_loaded('curl') && function_exists('curl_init');
            $system_variables[] = ["name" => "curl", "need" => "开启", "status" => $curl];
            //openssl
            $openssl = extension_loaded('openssl');
            $system_variables[] = ["name" => "openssl", "need" => "开启", "status" => $openssl];
            //gd
            $gd = extension_loaded('gd');
            $system_variables[] = ["name" => "GD库", "need" => "开启", "status" => $gd];
            //fileinfo
            $fileinfo = extension_loaded('fileinfo');
            $system_variables[] = ["name" => "fileinfo", "need" => "开启", "status" => $fileinfo];

            $root_path = str_replace("\\", DIRECTORY_SEPARATOR, dirname(__FILE__, 4));
            $root_path = str_replace("/", DIRECTORY_SEPARATOR, $root_path);
            $dirs_list = [
                ["path" => $root_path, "path_name" => "/", "name" => "整目录"],
                ["path" => $root_path . DIRECTORY_SEPARATOR . "app", "path_name" => "app", "name" => "app"],
                ["path" => $root_path . DIRECTORY_SEPARATOR . "public", "path_name" => "public", "name" => "public"],
                ["path" => $root_path . DIRECTORY_SEPARATOR . "config", "path_name" => "static", "name" => "static"],
                ["path" => $root_path . DIRECTORY_SEPARATOR . 'runtime', "path_name" => "runtime", "name" => "runtime"],
                ["path" => $root_path . DIRECTORY_SEPARATOR . 'addon', "path_name" => "addon", "name" => "安装目录"]
            ];

            //目录 可读 可写检测
            $is_dir = true;
            foreach ($dirs_list as $k => $v) {
                $is_readable = is_readable($v["path"]);
                $is_write = $this->is_write($v["path"]);
                $dirs_list[$k]["is_readable"] = $is_readable;
                $dirs_list[$k]["is_write"] = $is_write;
                if ($is_readable == false || $is_write == false) {
                    $is_dir = false;
                }
            }
            $this->assign("root_path", $root_path);
            $this->assign("system_variables", $system_variables);
            $this->assign("phpv", $phpv);
            $this->assign("server", $server);
            $this->assign("host", $host);
            $this->assign("os", $os);
            $this->assign("name", $name);
            $this->assign("verison", $verison);
            $this->assign("dirs_list", $dirs_list);
            if ($verison && $pdo && $curl && $openssl && $gd && $fileinfo && $is_dir) {
                $continue = true;
            } else {
                $continue = false;
            }

            $this->assign("continue", $continue);
            return $this->fetch('index/step-2');
        } elseif ($step == 3) {
            return $this->fetch('index/step-3');
        } elseif ($step == 4) {
            set_time_limit(300);
            //数据库
            $dbport = input("dbport", "3306");
            $dbhost = input("dbhost", "127.0.0.1");
            $dbuser = input("dbuser", "");
            $dbpwd = input("dbpwd", "");
            $dbname = input("dbname", "");//数据库名称
            $dbprefix = input("dbprefix", "");//前缀
            //管理员
            $username = input('username', "");
            $password = input('password', "");
            $password2 = input('password2', "");
            if ($dbhost == '' || $dbuser == '') {
                return BackCode([], 203, '数据库链接配置信息丢失');
            }
            if ($dbprefix == '') {
                return BackCode([], 203, '数据表前缀不能为空');
            }
            //数据库连接测试
            $conn = @mysqli_connect($dbhost, $dbuser, $dbpwd, "", $dbport);
            if (!$conn) {
                return BackCode([], 203, '连接数据库失败！请检查连接参数！');
            }
            //管理员
            if ($username == '' || $password == '') {
                return BackCode([], 203, '管理员信息不能为空！');
            }

            if ($password != $password2) {
                return BackCode([], 203, '两次密码输入不一样，请重新输入！');
            }
            $install = App()->getRootPath() . "app/install/database.sql";
            if (!file_exists($install)) {
                return BackCode([], 203, '没有找到数据库文件');
            }

            //数据库可写和是否存在测试
            $empty_db = mysqli_select_db($conn, $dbname);
            if ($empty_db) {
                $sql = "DROP DATABASE `$dbname`";
                $retval = mysqli_query($conn, $sql);
                if (!$retval) {
                    return BackCode([], 203, '删除数据库失败！');
                }
            }

            //如果数据库不存在，我们就进行创建。
            $dbsql = "CREATE DATABASE `$dbname`";
            $db_create = mysqli_query($conn, $dbsql);
            if (!$db_create) {
                return BackCode([], 203, '创建数据库失败，请确认是否有足够的权限！');
            }
            //链接数据库
            @mysqli_select_db($conn, $dbname);
            @mysqli_query($conn, "SET NAMES utf8mb4");
            $SqlService = new SqlService();
            $sql = $SqlService->getSqlFromFile($install, false, ['reno_' => $dbprefix]);
            $id=GetSnowID();
            $sql[]="INSERT INTO `".$dbprefix."admin_user` (id, name, create_time,create_id,is_super,user,upass) VALUES ('".$id."', '超级管理员', '".date('Y-m-d H:i:s')."','".$id."','1','".$username."','".md5($password)."')";
            foreach ($sql as $k => $v) {
                try {
                    @mysqli_query($conn, $v);
                } catch (\Exception $e) {
                    return BackCode([], 203, '数据库解析失败');
                }
            }
            @mysqli_close($conn);
            $datas = [
                'hostname' => $dbhost,
                'database' => $dbname,
                'username' => $dbuser,
                'password' => $dbpwd,
                'prefix' => $dbprefix,
                'hostport' => $dbport
            ];
            $this->env($datas);
            $fp = fopen($this->lock_file, "w");
            if ($fp == false) {
                return BackCode([], 203, '写入失败，请检查目录');
            }
            fwrite($fp, '已安装');
            fclose($fp);
            return BackCode();
        }
    }

    public function env($datas)
    {

        $path = App()->getRootPath() . 'example.env';
        $example = file_get_contents($path); // 读取文件内容
        $pattern = "/'([^']*)'/";
        preg_match_all($pattern, $example, $matches);
        $arr = $matches[1];
        foreach ($arr as $k => $v) {
            $item = explode('.', $v);
            $field = $item[1];
            $value = !empty($datas[$field]) ? $datas[$field] : '';
            switch ($item[0]) {
                case "app":
                    $example = str_replace("'" . $v . "'", 'true', $example);
                    break;
                case "database":
                case "redis":
                case "aliyun":
                case "qiniu":
                case "qcloud":
                    $example = str_replace("'" . $v . "'", $value, $example);
                    break;
            }
        }
        getCreatetxt(App()->getRootPath() . '.env', $example);
    }


    public function installSuccess()
    {
        return $this->fetch('index/step-4');
    }

    /**
     * 测试数据库
     */
    public function testDb($dbhost = '', $dbport = '', $dbuser = '', $dbpwd = '', $dbname = '')
    {
        $dbport = input("dbport", "");
        $dbhost = input("dbhost", "");
        $dbuser = input("dbuser", "");
        $dbpwd = input("dbpwd", "");
        $dbname = input("dbname", "");
        try {

            if ($dbport != "" && $dbhost != "") {
                $dbhost = $dbport != '3306' ? $dbhost . ':' . $dbport : $dbhost;
            }

            if ($dbhost == '' || $dbuser == '') {
                return BackCode([], '203', '数据库账号或密码不能为空');
            }

            if (!function_exists("mysqli_connect")) {

                return BackCode([], '203', 'mysqli扩展类必须开启');
            }

            $conn = @mysqli_connect($dbhost, $dbuser, $dbpwd);
            if ($conn) {
                if (empty($dbname)) {
                    $result = [
                        "code" => 0,
                        "msg" => "数据库连接成功"
                    ];
                } else {
                    if (@mysqli_select_db($conn, $dbname)) {
                        $result = [
                            "code" => 2,
                            "msg" => "数据库存在，系统将覆盖数据库"
                        ];
                    } else {
                        $result = [
                            "code" => 0,
                            "msg" => "数据库不存在,系统将自动创建"
                        ];
                    }
                }
            } else {
                $result = [
                    "code" => 203,
                    "msg" => "数据库连接失败！"
                ];

            }
            @mysqli_close($conn);
            return BackCode([], $result['code'], $result['msg']);
        } catch (\Exception $e) {
            $result = [
                "code" => -1,
                "msg" => $e->getMessage()
            ];
            return BackCode([], $result['code'], $result['msg']);
        }
    }



    function str_replace_first($search, $replace, $subject)
    {
        return implode($replace, explode($search, $subject, 2));
    }

}